小数点以下を切り上げる場合の商を求める方法【競技プログラミング】
有名な内容だと思うが、自分用にメモ
整数型同士の割り算は切り捨てられる。
a, bを整数型(a, b>0)とするとき, a/bを計算すると小数点以下は切り捨てられる。
例)
(i) a=4, b=2
4/2=2
整数型同士の計算の場合は小数点以下は切り捨てられ、2となる。
(ii)a=5, b=2
5/2=2.5
整数型同士の計算の場合は小数点以下は切り捨てられ、2となる。
通常、整数型同士の割り算は切り捨てられ、そのままだと切り上げることはできない。
切り上げるためにはどうするか?
を計算し、小数点以下を切り下げると、a/bの小数点以下を切り上げた結果が得られる。
a=4, b=2
(4+2-1)/2=5/2=2.5
の小数点以下を切り捨てると、2となる。
確かに4/2=2で小数点以下を切り上げると2だから合ってる。
a=5,b=2
(5+2-1)/2=6/2=3
の小数点以下を切り捨てると、3となる。
両方ともa/bの小数点以下を切り上げた結果になっている。
証明
[]をガウス記号とする。(ここでは、小数点以下を切り捨てる程度の意味)
aがbで割り切れるか割り切れないかで場合分けする。
(i) aがbで割り切れる
a=bkとおける(kは整数)。この時,
a/b=kの小数点以下を切り上げてもkであるから、確かに合っている。
(ii) aがbで割り切れない
aをbで割った時の余りをlと置くと, a=bk+lとおける(k,lは整数, ただし, 0<l<b)。この時,
a/b=k+l/bの小数点以下を切り上げると、kは整数部分で、l/bは小数部分であるから、確かにk+1となり結果は合っている。
実装
C++でプログラムを組み、確認した。
#include <iostream>
using namespace std;
int main(){
int a, b;
cin >> a >> b;
cout << "a/b=" << a/b << endl;
cout << "(a+b-1)/b=" << (a+b-1)/b << endl;
return 0;
}
(i)a=4, b=2
$ ./a.out
4 2
a/b=2
(a+b-1)/b=2
(ii)a=5, b=2
$ ./a.out
5 2
a/b=2
(a+b-1)/b=3
結論
(a+b-1)/bを計算し、小数点以下を切り捨てると, a/bの小数点以下を切り上げた結果が得られる。
Penpen7のブログ